import React, { useState } from 'react';
import { Cascader } from 'antd';
import areaList from '@/components/CityPicker/area';
import { useMount } from 'react-use';
import { getLocale } from 'umi';
import keyBy from 'lodash/keyBy';

/**
 * 将所有数据拉平
 * @param list
 * @returns {[]}
 */
const flatten = (list = []) => {
    let tempArray = [];
    list.forEach(item => {
        tempArray.push(item);
        if (item?.children && item?.children.length > 0) {
            tempArray = tempArray.concat(flatten(item.children));
        }
    });
    return tempArray;
};

// 将数据拉平
const flattenAreaList = flatten(areaList);

// 以编码作为索引,缓存数据
const areaCodeGroup = keyBy(flattenAreaList, 'code');

// 以id作为索引，缓存数据
const areaIdGroup = keyBy(flattenAreaList, 'id');

/**
 * 根据编码获取对应的区域
 * @example getAreaItemByCode('350203000000') =>  {id: 2002, code:350203000000,  nameZh: '思明区', ...}
 * @param code 编码
 * @returns {*}
 */
const getAreaItemByCode = code => areaCodeGroup[code];

/**
 * 根据id获取对应的区域
 * @example getAreaItemById('2002') =>  {id: 2002, code:350203000000,  nameZh: '思明区', ...}
 * @param id
 * @returns {*}
 */
const getAreaItemById = id => areaIdGroup[id];

/**
 * 根据编码获取对应的全路径，
 * 1.当为【县】的编码时->【省】【市】【县】的数组
 * 2.当为【市】的编码时->【省】【市】的数组
 * 依此类推
 * @param code 编码
 * @returns {null|*[]}
 */
const getAreaItemPath = code => {
    if (!code) {
        return null;
    }

    const item = getAreaItemByCode(code);
    const result = [];
    let tempItem = item;

    // 获取所有父组节点，level === 0 的为国家
    while (tempItem != null && tempItem.level !== 0) {
        result.push(tempItem);

        const { parentId } = tempItem;
        if (parentId != null && parentId !== 0) {
            tempItem = getAreaItemById(parentId);
        }
    }

    // reverse后是父组到子组排列
    return result.reverse();
};

/**
 * 根据编码获取整个路径（省、市、区）的值
 * @example getValueArrayByChildValue('350203000000') => ["350000000000", "350200000000", "350203000000"]
 * @returns {*}
 */
const getValueArrayByChildValue = (code, field = 'code') => {
    const itemList = getAreaItemPath(code);

    return itemList != null ? itemList.map(item => item[field]) : null;
};

/**
 * 判断当前环境是否为中文
 * @returns {boolean}
 */
const isCN = () => /zh[-_]cn/gi.test(getLocale());

/**
 * 根据区域获取名称（有根据语言环境）
 * @param areaItem
 * @returns {string|*}
 */
const getNameByAreaItem = areaItem => {
    if (!areaItem) {
        return '';
    }

    return isCN() ? areaItem.nameZh : areaItem.nameEn;
};

/**
 * 根据编码获取名称
 * @example getFullNameByCode('350203000000') => '思明区'
 * @param code
 * @returns {string|*}
 */
const getNameByCode = code => getNameByAreaItem(getAreaItemByCode(code));

const getFullPropertyByAreaItemPath = (areaItemPath, propertyName, separator = '/') => {
    if (!areaItemPath || areaItemPath.length === 0) {
        return '';
    }

    if (typeof propertyName === 'function') {
        return areaItemPath.map(item => propertyName(item)).join(separator);
    }

    return areaItemPath.map(item => item[propertyName]).join(separator);
};

const getFullNameByAreaItemPath = (areaItemPath, separator = '/') => {
    const isChinese = isCN();

    return getFullPropertyByAreaItemPath(
        areaItemPath,
        item => (isChinese ? item.nameZh : item.nameEn),
        separator
    );
};

const getFullCodeByAreaItemPath = (areaItemPath, separator = '/') => getFullPropertyByAreaItemPath(
    areaItemPath, 'code', separator
);

/**
 * 根据编码获取全路径名
 * @example getFullNameByCode('350203000000') => '福建省/厦门市/思明区'
 * @param code 编码
 * @param separator 分隔符
 * @returns {string}
 */
const getFullNameByCode = (code, separator = '/') => getFullNameByAreaItemPath(getAreaItemPath(code), separator);

/**
 * 根据编码获取编码全路径名
 * @example getFullNameByCode('350203000000') => '350000000000/350200000000/350203000000'
 * @param code 编码
 * @param separator 分隔符
 * @returns {string}
 */
const getFullCodeByCode = (code, separator = '/') =>
    getFullPropertyByAreaItemPath(getAreaItemPath(code), 'code', separator);

/**
 * 根据区域获取名称（有根据语言环境）
 * @param areaItem
 * @param separator
 * @returns {string|*}
 */
const getReadableNameByAreaItem = (areaItem, separator = '/') => {
    if (!areaItem) {
        return '';
    }

    const name = isCN() ? areaItem.nameZh : areaItem.nameEn;

    if (name === '市辖区' || name === 'shixiaqu') {
        const { parentId } = areaItem;
        return `${getNameByAreaItem(getAreaItemById(parentId))}${separator}${name}`;
    }

    return name;
};

/**
 * 获取易读性的名称（如果当前城市为"市辖区"时，会再显示父级名称）
 * @param code
 * @param separator
 * @returns {string|*}
 */
const getReadableNameByCode = (code, separator = '/') =>
    getReadableNameByAreaItem(getAreaItemByCode(code), separator);

const CityCascader = React.forwardRef(
    ({ value, onChange, cityParentId, changeOnSelect = true, ...otherProps }, ref) => {
        const [isChinese, setIsChinese] = useState(true);

        const area = areaList.find(item => String(item.id) === String(cityParentId));
        const options = area?.children || [];
        const labelField = isChinese ? 'nameZh' : 'nameEn';

        if (typeof value === 'string') {
            onChange(getValueArrayByChildValue(value));
        }

        useMount(() => {
            setIsChinese(isCN);
        });

        return (
            <Cascader
                fieldNames={{
                    id: 'code',
                    label: labelField,
                    value: 'code'
                }}
                value={value}
                options={options}
                onChange={onChange}
                changeOnSelect={changeOnSelect}
                {...otherProps}
                ref={ref}
            />
        );
    }
);
export default CityCascader;

export {
    getAreaItemPath,
    getAreaItemById,
    getAreaItemByCode,
    getValueArrayByChildValue,
    getNameByAreaItem,
    getNameByCode,
    getFullNameByCode,
    getFullCodeByCode,
    getFullNameByAreaItemPath,
    getFullCodeByAreaItemPath,
    getReadableNameByAreaItem,
    getReadableNameByCode
};
